package dynamic_planning;

/**
 * @Author Yi Jun jie
 * @Date 2021/3/8 15:54
 * 474. 一和零
 * 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。
 * 请你找出并返回 strs 的最大子集的大小，该子集中 最多 有 m 个 0 和 n 个 1 。
 * 如果 x 的所有元素也是 y 的元素，集合 x 是集合 y 的 子集 。
 * <p>
 * 示例：
 * 输入：strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3
 * 输出：4
 * 解释：最多有 5 个 0 和 3 个 1 的最大子集是 {"10","0001","1","0"} ，因此答案是 4 。
 * 其他满足题意但较小的子集包括 {"0001","1"} 和 {"10","1","0"} 。{"111001"} 不满足题意，因为它含 4 个 1 ，大于 n 的值 3 。
 * <p>
 * 输入：strs = ["10", "0", "1"], m = 1, n = 1
 * 输出：2
 * 解释：最大的子集是 {"0", "1"} ，所以答案是 2 。
 *
 */
public class LeetCode474Plus {
    public static void main(String[] args) {
        String[] strs = {"1001", "10", "0001",  "1", "0"};
        System.out.println(findMaxFormPlus(strs, 5, 3));
    }

    public static int findMaxForm(String[] strs, int m, int n) {
        int[][] f = new int[m + 1][n + 1];
        int[] MN;
        for (int i = 0; i <= m; i++) {//m 横坐标
            for (int j = 0; j <= n; j++) {//n 纵坐标
                for (int k = 0; k < strs.length; k++) {
                    MN = getMN(strs[k]);
                    if (i >= MN[0] && j >= MN[1]) {
                        f[i][j] = Math.max(f[i - MN[0]][j - MN[1]] + 1, f[i][j]);
                    }
                }
            }
        }
        return f[m][n];
    }

    public static int findMaxFormPlus(String[] strs, int m, int n) {
        int strsNum = strs.length;
        int[][] f = new int[m + 1][n + 1];
        for (int i = 0; i < strsNum; i++) {//这里是一个一个的用掉
            int[] cnt = getMN(strs[i]);
            //这里要从大到小
            for (int j = m; j >= 0; j--) {
                //函数对应的参数变化进行循环
                for (int k = n; k >= 0; k--) {
                    if (j >= cnt[0] && k >= cnt[1]) {
                        f[j][k] = Math.max(f[j][k], f[j - cnt[0]][k - cnt[1]] + 1);
                    }
                }
            }
        }
        return f[m][n];
    }

    public static int[] getMN(String s) {
        int[] c = new int[2];
        for (int i = 0; i < s.length(); i++) {
            c[s.charAt(i) - '0']++;
        }
        return c;
    }
}
